package com.fc.primary.stack;

/**
 * @program: fc-java->MyStack
 * @description: 手写栈
 * @author: G_Y
 * @create: 2019-09-01 12:28
 * 堆栈————抽象意义上的数据结构，非实际性的物理数据结构
 **/
public class MyStack<T> {
    /*
     * 栈特性：先进后出————插入、删除都是在尾部(栈顶)
     * 压栈————粮仓，先倒入得粮食最后才会被挖出来
     */
    /**
     * 用数组来实现栈
     * 循环数组
     */
    final Object[] items;

    /**
     * pop指针
     */
    int popIndex;

    /**
     * push指针
     */
    int putIndex;

    /**
     * 栈实际存储的元素量
     */
    int count;

    /**
     * @param capacity 构造方法
     */
    public MyStack(int capacity) {
        items = new Object[capacity];
    }

    /**
     * 入栈
     *
     * @return
     */
    public boolean push(T item) {
        if (count == items.length) {
            throw new RuntimeException("满啦");
        }
        items[putIndex] = item;
        this.popIndex = putIndex;
        this.updatePutIndex();
        count++;
        System.out.println("入栈元素" + item);
        return true;
    }

    /**
     * 出栈
     *
     * @return
     */
    public T pop() {
        if (count < 1) {
            throw new RuntimeException("空啦");
        }
        T item = (T) items[popIndex];
        items[popIndex] = null;
        updatePopIndex();
        count--;
        return item;
    }

    /**
     * 栈存储的元素量
     *
     * @return
     */
    public int size() {
        return count;
    }

    /**
     * 获取栈容量
     *
     * @return
     */
    public int getCap() {
        return items.length;
    }


    private void updatePutIndex() {
        if (putIndex == items.length - 1) {
            putIndex = 0;
            return;
        }
        putIndex++;
    }

    private void updatePopIndex() {
        if (popIndex == 0) {
            popIndex = items.length - 1;
            return;
        }
        popIndex--;
    }
}
